#!/bin/bash

# 脚本测试工具
# 功能：验证所有脚本的语法正确性和基本功能
# 版本：1.0
# 作者：脚本测试工具生成器

# 设置脚本严格模式
set -euo pipefail

# 全局变量定义
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LOG_DIR="${SCRIPT_DIR}/logs"
TEMP_DIR="${SCRIPT_DIR}/temp"

# 测试配置
TEST_SYNTAX_ONLY=false
TEST_HELP_ONLY=false
VERBOSE_MODE=false
EXIT_ON_FAILURE=false

# 测试结果统计
TOTAL_TESTS=0
PASSED_TESTS=0
FAILED_TESTS=0
SKIPPED_TESTS=0

# 日志级别
LOG_LEVEL_DEBUG=0
LOG_LEVEL_INFO=1
LOG_LEVEL_WARN=2
LOG_LEVEL_ERROR=3
LOG_LEVEL_FATAL=4
CURRENT_LOG_LEVEL=$LOG_LEVEL_INFO

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# =============================================================================
# 工具函数
# =============================================================================

# 显示帮助信息
show_help() {
    cat << EOF
脚本测试工具

用法: $0 [选项]

选项:
    -h, --help          显示此帮助信息
    -v, --version       显示脚本版本
    -s, --syntax-only   仅测试语法正确性
    -p, --help-only     仅测试帮助信息显示
    -V, --verbose       详细模式，显示所有测试输出
    -e, --exit-on-fail  遇到失败时立即退出
    --debug             启用调试模式

功能:
    验证所有脚本的语法正确性
    测试脚本的帮助信息显示
    验证脚本的基本功能（不实际安装）
    检查脚本的执行权限

测试的脚本:
    - install_all.sh
    - install_jdk.sh
    - install_maven.sh
    - verify_installation.sh

EOF
}

# 显示版本信息
show_version() {
    echo "脚本测试工具 v1.0"
}

# 日志记录函数
log_message() {
    local level="$1"
    local message="$2"
    local module="${3:-MAIN}"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    local pid=$$
    
    # 检查日志级别
    case $level in
        "DEBUG") [[ $CURRENT_LOG_LEVEL -gt $LOG_LEVEL_DEBUG ]] && return ;;
        "INFO")  [[ $CURRENT_LOG_LEVEL -gt $LOG_LEVEL_INFO ]] && return ;;
        "WARN")  [[ $CURRENT_LOG_LEVEL -gt $LOG_LEVEL_WARN ]] && return ;;
        "ERROR") [[ $CURRENT_LOG_LEVEL -gt $LOG_LEVEL_ERROR ]] && return ;;
        "FATAL") [[ $CURRENT_LOG_LEVEL -gt $LOG_LEVEL_FATAL ]] && return ;;
    esac
    
    # 格式化日志消息
    local log_entry="[${timestamp}] [${level}] [${module}] [${pid}] ${message}"
    
    # 写入日志文件
    if [[ -d "$LOG_DIR" ]]; then
        echo "$log_entry" >> "${LOG_DIR}/test_$(date +%Y%m%d_%H%M%S).log"
    fi
    
    # 控制台输出
    if [[ "$VERBOSE_MODE" == true ]]; then
        case $level in
            "DEBUG") echo -e "${BLUE}${log_entry}${NC}" ;;
            "INFO")  echo -e "${GREEN}${log_entry}${NC}" ;;
            "WARN")  echo -e "${YELLOW}${log_entry}${NC}" ;;
            "ERROR") echo -e "${RED}${log_entry}${NC}" ;;
            "FATAL") echo -e "${RED}${log_entry}${NC}" ;;
            *)       echo "$log_entry" ;;
        esac
    fi
}

# 便捷日志函数
log_debug() { log_message "DEBUG" "$1" "${2:-MAIN}"; }
log_info() { log_message "INFO" "$1" "${2:-MAIN}"; }
log_warn() { log_message "WARN" "$1" "${2:-MAIN}"; }
log_error() { log_message "ERROR" "$1" "${2:-MAIN}"; }
log_fatal() { log_message "FATAL" "$1" "${2:-MAIN}"; }

# 显示测试结果
show_test_result() {
    local test_name="$1"
    local result="$2"
    local message="${3:-}"
    
    ((TOTAL_TESTS++))
    
    case $result in
        "PASS")
            echo -e "${GREEN}✓ PASS${NC} $test_name"
            ((PASSED_TESTS++))
            ;;
        "FAIL")
            echo -e "${RED}✗ FAIL${NC} $test_name"
            if [[ -n "$message" ]]; then
                echo -e "  ${RED}错误: $message${NC}"
            fi
            ((FAILED_TESTS++))
            if [[ "$EXIT_ON_FAILURE" == true ]]; then
                exit 1
            fi
            ;;
        "SKIP")
            echo -e "${YELLOW}- SKIP${NC} $test_name"
            if [[ -n "$message" ]]; then
                echo -e "  ${YELLOW}原因: $message${NC}"
            fi
            ((SKIPPED_TESTS++))
            ;;
    esac
}

# 创建必要的目录
create_directories() {
    if [[ ! -d "$LOG_DIR" ]]; then
        mkdir -p "$LOG_DIR"
    fi
    
    if [[ ! -d "$TEMP_DIR" ]]; then
        mkdir -p "$TEMP_DIR"
    fi
}

# =============================================================================
# 测试函数
# =============================================================================

# 测试脚本语法
test_script_syntax() {
    local script="$1"
    local script_name=$(basename "$script")
    
    log_info "测试脚本语法: $script_name" "SYNTAX_TEST"
    
    if [[ ! -f "$script" ]]; then
        show_test_result "语法测试: $script_name" "FAIL" "脚本文件不存在"
        return 1
    fi
    
    # 使用bash -n检查语法
    if bash -n "$script" 2>/dev/null; then
        show_test_result "语法测试: $script_name" "PASS"
        log_info "语法测试通过: $script_name" "SYNTAX_TEST"
        return 0
    else
        local error_output=$(bash -n "$script" 2>&1 || true)
        show_test_result "语法测试: $script_name" "FAIL" "$error_output"
        log_error "语法测试失败: $script_name - $error_output" "SYNTAX_TEST"
        return 1
    fi
}

# 测试帮助信息
test_script_help() {
    local script="$1"
    local script_name=$(basename "$script")
    
    log_info "测试帮助信息: $script_name" "HELP_TEST"
    
    if [[ ! -f "$script" ]]; then
        show_test_result "帮助测试: $script_name" "FAIL" "脚本文件不存在"
        return 1
    fi
    
    # 测试 --help 参数
    local help_output
    if help_output=$("$script" --help 2>&1); then
        # 检查帮助信息是否包含基本内容
        if echo "$help_output" | grep -q "用法\|usage\|Usage"; then
            show_test_result "帮助测试: $script_name" "PASS"
            log_info "帮助测试通过: $script_name" "HELP_TEST"
            return 0
        else
            show_test_result "帮助测试: $script_name" "FAIL" "帮助信息格式不正确"
            log_error "帮助测试失败: $script_name - 帮助信息格式不正确" "HELP_TEST"
            return 1
        fi
    else
        show_test_result "帮助测试: $script_name" "FAIL" "无法显示帮助信息"
        log_error "帮助测试失败: $script_name - 无法显示帮助信息" "HELP_TEST"
        return 1
    fi
}

# 测试版本信息
test_script_version() {
    local script="$1"
    local script_name=$(basename "$script")
    
    log_info "测试版本信息: $script_name" "VERSION_TEST"
    
    if [[ ! -f "$script" ]]; then
        show_test_result "版本测试: $script_name" "FAIL" "脚本文件不存在"
        return 1
    fi
    
    # 测试 --version 参数
    local version_output
    if version_output=$("$script" --version 2>&1); then
        # 检查版本信息是否包含基本内容
        if echo "$version_output" | grep -q "v[0-9]\|version\|Version"; then
            show_test_result "版本测试: $script_name" "PASS"
            log_info "版本测试通过: $script_name" "VERSION_TEST"
            return 0
        else
            show_test_result "版本测试: $script_name" "FAIL" "版本信息格式不正确"
            log_error "版本测试失败: $script_name - 版本信息格式不正确" "VERSION_TEST"
            return 1
        fi
    else
        show_test_result "版本测试: $script_name" "FAIL" "无法显示版本信息"
        log_error "版本测试失败: $script_name - 无法显示版本信息" "VERSION_TEST"
        return 1
    fi
}

# 测试脚本权限
test_script_permissions() {
    local script="$1"
    local script_name=$(basename "$script")
    
    log_info "测试脚本权限: $script_name" "PERMISSION_TEST"
    
    if [[ ! -f "$script" ]]; then
        show_test_result "权限测试: $script_name" "FAIL" "脚本文件不存在"
        return 1
    fi
    
    # 检查是否可执行
    if [[ -x "$script" ]]; then
        show_test_result "权限测试: $script_name" "PASS"
        log_info "权限测试通过: $script_name" "PERMISSION_TEST"
        return 0
    else
        show_test_result "权限测试: $script_name" "FAIL" "脚本不可执行"
        log_error "权限测试失败: $script_name - 脚本不可执行" "PERMISSION_TEST"
        return 1
    fi
}

# 测试脚本基本功能（不实际安装）
test_script_functionality() {
    local script="$1"
    local script_name=$(basename "$script")
    
    log_info "测试脚本基本功能: $script_name" "FUNCTIONALITY_TEST"
    
    if [[ ! -f "$script" ]]; then
        show_test_result "功能测试: $script_name" "FAIL" "脚本文件不存在"
        return 1
    fi
    
    # 根据不同脚本测试不同功能
    case "$script_name" in
        "install_all.sh")
            # 测试主脚本的参数解析
            if "$script" --help >/dev/null 2>&1 && \
               "$script" --version >/dev/null 2>&1; then
                show_test_result "功能测试: $script_name" "PASS"
                log_info "功能测试通过: $script_name" "FUNCTIONALITY_TEST"
                return 0
            else
                show_test_result "功能测试: $script_name" "FAIL" "参数解析失败"
                log_error "功能测试失败: $script_name - 参数解析失败" "FUNCTIONALITY_TEST"
                return 1
            fi
            ;;
        "install_jdk.sh"|"install_maven.sh")
            # 测试安装脚本的参数解析
            if "$script" --help >/dev/null 2>&1 && \
               "$script" --version >/dev/null 2>&1; then
                show_test_result "功能测试: $script_name" "PASS"
                log_info "功能测试通过: $script_name" "FUNCTIONALITY_TEST"
                return 0
            else
                show_test_result "功能测试: $script_name" "FAIL" "参数解析失败"
                log_error "功能测试失败: $script_name - 参数解析失败" "FUNCTIONALITY_TEST"
                return 1
            fi
            ;;
        "verify_installation.sh")
            # 测试校验脚本的参数解析
            if "$script" --help >/dev/null 2>&1 && \
               "$script" --version >/dev/null 2>&1; then
                show_test_result "功能测试: $script_name" "PASS"
                log_info "功能测试通过: $script_name" "FUNCTIONALITY_TEST"
                return 0
            else
                show_test_result "功能测试: $script_name" "FAIL" "参数解析失败"
                log_error "功能测试失败: $script_name - 参数解析失败" "FUNCTIONALITY_TEST"
                return 1
            fi
            ;;
        *)
            show_test_result "功能测试: $script_name" "SKIP" "未知脚本类型"
            log_warn "功能测试跳过: $script_name - 未知脚本类型" "FUNCTIONALITY_TEST"
            return 0
            ;;
    esac
}

# 测试错误处理
test_script_error_handling() {
    local script="$1"
    local script_name=$(basename "$script")
    
    log_info "测试错误处理: $script_name" "ERROR_TEST"
    
    if [[ ! -f "$script" ]]; then
        show_test_result "错误处理测试: $script_name" "FAIL" "脚本文件不存在"
        return 1
    fi
    
    # 测试无效参数
    if "$script" --invalid-parameter 2>/dev/null; then
        show_test_result "错误处理测试: $script_name" "FAIL" "应该拒绝无效参数"
        log_error "错误处理测试失败: $script_name - 应该拒绝无效参数" "ERROR_TEST"
        return 1
    else
        show_test_result "错误处理测试: $script_name" "PASS"
        log_info "错误处理测试通过: $script_name" "ERROR_TEST"
        return 0
    fi
}

# =============================================================================
# 主测试函数
# =============================================================================

# 运行所有测试
run_all_tests() {
    local scripts=(
        "install_all.sh"
        "install_jdk.sh"
        "install_maven.sh"
        "verify_installation.sh"
    )
    
    echo "========================================"
    echo "           开始脚本测试"
    echo "========================================"
    echo
    
    for script in "${scripts[@]}"; do
        local script_path="${SCRIPT_DIR}/${script}"
        
        echo "测试脚本: $script"
        echo "----------------------------------------"
        
        # 测试脚本权限
        test_script_permissions "$script_path"
        
        # 测试语法
        test_script_syntax "$script_path"
        
        # 如果只测试语法，跳过其他测试
        if [[ "$TEST_SYNTAX_ONLY" == true ]]; then
            echo
            continue
        fi
        
        # 测试帮助信息
        if [[ "$TEST_HELP_ONLY" == false ]]; then
            test_script_help "$script_path"
            test_script_version "$script_path"
            test_script_functionality "$script_path"
            test_script_error_handling "$script_path"
        else
            test_script_help "$script_path"
        fi
        
        echo
    done
}

# 显示测试摘要
show_test_summary() {
    echo "========================================"
    echo "           测试结果摘要"
    echo "========================================"
    echo
    echo "总测试项目: $TOTAL_TESTS"
    echo -e "通过项目: ${GREEN}$PASSED_TESTS${NC}"
    echo -e "失败项目: ${RED}$FAILED_TESTS${NC}"
    echo -e "跳过项目: ${YELLOW}$SKIPPED_TESTS${NC}"
    echo
    
    if [[ $FAILED_TESTS -eq 0 ]]; then
        echo -e "${GREEN}所有测试通过！${NC}"
        echo
        return 0
    else
        echo -e "${RED}有测试失败，请检查上述错误信息${NC}"
        echo
        return 1
    fi
}

# =============================================================================
# 主函数
# =============================================================================

# 解析命令行参数
parse_arguments() {
    while [[ $# -gt 0 ]]; do
        case $1 in
            -h|--help)
                show_help
                exit 0
                ;;
            -v|--version)
                show_version
                exit 0
                ;;
            -s|--syntax-only)
                TEST_SYNTAX_ONLY=true
                shift
                ;;
            -p|--help-only)
                TEST_HELP_ONLY=true
                shift
                ;;
            -V|--verbose)
                VERBOSE_MODE=true
                shift
                ;;
            -e|--exit-on-fail)
                EXIT_ON_FAILURE=true
                shift
                ;;
            --debug)
                CURRENT_LOG_LEVEL=$LOG_LEVEL_DEBUG
                shift
                ;;
            *)
                echo "未知参数: $1"
                show_help
                exit 1
                ;;
        esac
    done
}

# 主测试流程
main() {
    # 解析命令行参数
    parse_arguments "$@"
    
    # 创建必要目录
    create_directories
    
    # 运行所有测试
    run_all_tests
    
    # 显示测试摘要
    show_test_summary
    
    # 根据测试结果退出
    if [[ $FAILED_TESTS -eq 0 ]]; then
        exit 0
    else
        exit 1
    fi
}

# 脚本入口点
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
    main "$@"
fi